"""
视频相关数据模型

定义视频文件、元数据和分类相关的数据模型。
"""

from datetime import datetime
from typing import Dict, Any, Optional, List
import json

from sqlalchemy import Column, Integer, String, Float, Text, Boolean, ForeignKey, Index, DateTime
from sqlalchemy.orm import relationship, backref

from .base import BaseModel, JSONField


class Video(BaseModel):
    """
    视频文件模型
    
    存储视频文件的基本信息。
    """
    
    __tablename__ = 'videos'
    
    # 文件信息
    file_path = Column(String(500), unique=True, nullable=False, index=True)
    file_name = Column(String(255), nullable=False, index=True)
    file_size = Column(Integer, nullable=False)  # 字节
    file_hash = Column(String(64), nullable=True, index=True)  # SHA256哈希
    
    # 视频基本属性
    duration = Column(Float, nullable=True)  # 秒
    width = Column(Integer, nullable=True)
    height = Column(Integer, nullable=True)
    fps = Column(Float, nullable=True)
    bitrate = Column(Integer, nullable=True)
    codec = Column(String(50), nullable=True)
    format = Column(String(50), nullable=True)
    
    # 状态信息
    is_processed = Column(Boolean, default=False, nullable=False)
    is_available = Column(Boolean, default=True, nullable=False)
    last_accessed = Column(DateTime, nullable=True)
    
    # 关联关系
    video_metadata = relationship("VideoMetadata", back_populates="video", uselist=False, cascade="all, delete-orphan")
    classifications = relationship("VideoClassification", back_populates="video", cascade="all, delete-orphan")
    processing_tasks = relationship("ProcessingTask", back_populates="video", cascade="all, delete-orphan")
    
    # 索引
    __table_args__ = (
        Index('idx_video_file_info', 'file_name', 'file_size'),
        Index('idx_video_dimensions', 'width', 'height'),
        Index('idx_video_status', 'is_processed', 'is_available'),
    )
    
    @property
    def file_size_mb(self) -> float:
        """文件大小（MB）"""
        return self.file_size / (1024 * 1024) if self.file_size else 0.0
    
    @property
    def aspect_ratio(self) -> Optional[float]:
        """宽高比"""
        if self.width and self.height:
            return self.width / self.height
        return None
    
    @property
    def resolution(self) -> Optional[str]:
        """分辨率字符串"""
        if self.width and self.height:
            return f"{self.width}x{self.height}"
        return None
    
    @property
    def duration_formatted(self) -> Optional[str]:
        """格式化的时长"""
        if self.duration:
            minutes = int(self.duration // 60)
            seconds = int(self.duration % 60)
            return f"{minutes:02d}:{seconds:02d}"
        return None
    
    def get_latest_classification(self) -> Optional['VideoClassification']:
        """获取最新的分类结果"""
        if self.classifications:
            return max(self.classifications, key=lambda c: c.created_at)
        return None
    
    def get_classification_by_type(self, classifier_type: str) -> Optional['VideoClassification']:
        """根据分类器类型获取分类结果"""
        for classification in self.classifications:
            if classification.classifier_type == classifier_type:
                return classification
        return None
    
    def to_dict(self, include_relationships: bool = False) -> Dict[str, Any]:
        """转换为字典，包含计算属性"""
        result = super().to_dict(include_relationships)
        
        # 添加计算属性
        result.update({
            'file_size_mb': self.file_size_mb,
            'aspect_ratio': self.aspect_ratio,
            'resolution': self.resolution,
            'duration_formatted': self.duration_formatted
        })
        
        # 添加最新分类信息
        latest_classification = self.get_latest_classification()
        if latest_classification:
            result['latest_classification'] = latest_classification.to_dict()
        
        return result


class VideoMetadata(BaseModel):
    """
    视频元数据模型
    
    存储视频的详细元数据信息。
    """
    
    __tablename__ = 'video_metadata'
    
    # 关联视频
    video_id = Column(Integer, ForeignKey('videos.id'), nullable=False, unique=True)
    video = relationship("Video", back_populates="video_metadata")
    
    # 技术元数据
    container_format = Column(String(50), nullable=True)
    video_codec = Column(String(50), nullable=True)
    audio_codec = Column(String(50), nullable=True)
    pixel_format = Column(String(50), nullable=True)
    color_space = Column(String(50), nullable=True)
    
    # 音频信息
    audio_channels = Column(Integer, nullable=True)
    audio_sample_rate = Column(Integer, nullable=True)
    audio_bitrate = Column(Integer, nullable=True)
    
    # 视频质量信息
    quality_score = Column(Float, nullable=True)  # 0.0-1.0
    brightness = Column(Float, nullable=True)
    contrast = Column(Float, nullable=True)
    saturation = Column(Float, nullable=True)
    sharpness = Column(Float, nullable=True)
    
    # 内容分析
    scene_count = Column(Integer, nullable=True)
    motion_level = Column(Float, nullable=True)  # 0.0-1.0
    
    # 原始元数据（JSON格式）
    raw_metadata = Column(Text, nullable=True)
    
    # 提取信息
    extracted_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    extractor_version = Column(String(50), nullable=True)
    
    def get_raw_metadata_dict(self) -> Dict[str, Any]:
        """获取原始元数据字典"""
        from .base import JSONFieldHelper
        return JSONFieldHelper.deserialize(self.raw_metadata) or {}
    
    def set_raw_metadata_dict(self, data: Dict[str, Any]) -> None:
        """设置原始元数据字典"""
        self.raw_metadata = JSONField.serialize(data)
    
    def to_dict(self, include_relationships: bool = False) -> Dict[str, Any]:
        """转换为字典"""
        result = super().to_dict(include_relationships)
        
        # 解析原始元数据
        result['raw_metadata_dict'] = self.get_raw_metadata_dict()
        
        return result


class VideoClassification(BaseModel):
    """
    视频分类结果模型
    
    存储AI分类的结果。
    """
    
    __tablename__ = 'video_classifications'
    
    # 关联视频
    video_id = Column(Integer, ForeignKey('videos.id'), nullable=False)
    video = relationship("Video", back_populates="classifications")
    
    # 分类信息
    category = Column(String(50), nullable=False, index=True)
    subcategory = Column(String(50), nullable=True)
    confidence = Column(Float, nullable=False)  # 0.0-1.0
    
    # 分类器信息
    classifier_type = Column(String(50), nullable=False, index=True)
    classifier_version = Column(String(50), nullable=True)
    model_name = Column(String(100), nullable=True)
    
    # 分类详情
    reasoning = Column(Text, nullable=True)
    features = Column(Text, nullable=True)  # JSON格式的特征列表
    
    # 处理信息
    processing_time = Column(Float, nullable=True)  # 秒
    frames_analyzed = Column(Integer, nullable=True)
    
    # 质量评估
    quality_score = Column(Float, nullable=True)  # 0.0-1.0
    
    # 原始响应
    raw_response = Column(Text, nullable=True)
    
    # 验证信息
    is_verified = Column(Boolean, default=False, nullable=False)
    verified_by = Column(String(100), nullable=True)
    verified_at = Column(DateTime, nullable=True)
    
    # 索引
    __table_args__ = (
        Index('idx_classification_category', 'category', 'confidence'),
        Index('idx_classification_classifier', 'classifier_type', 'created_at'),
        Index('idx_classification_video_classifier', 'video_id', 'classifier_type'),
    )
    
    def get_features_list(self) -> List[str]:
        """获取特征列表"""
        return JSONField.deserialize(self.features) or []
    
    def set_features_list(self, features: List[str]) -> None:
        """设置特征列表"""
        self.features = JSONField.serialize(features)
    
    def get_raw_response_dict(self) -> Dict[str, Any]:
        """获取原始响应字典"""
        return JSONField.deserialize(self.raw_response) or {}
    
    def set_raw_response_dict(self, data: Dict[str, Any]) -> None:
        """设置原始响应字典"""
        self.raw_response = JSONField.serialize(data)
    
    @property
    def confidence_level(self) -> str:
        """置信度等级"""
        if self.confidence >= 0.9:
            return "very_high"
        elif self.confidence >= 0.7:
            return "high"
        elif self.confidence >= 0.5:
            return "medium"
        elif self.confidence >= 0.3:
            return "low"
        else:
            return "very_low"
    
    def verify(self, verified_by: str) -> None:
        """验证分类结果"""
        self.is_verified = True
        self.verified_by = verified_by
        self.verified_at = datetime.utcnow()
    
    def to_dict(self, include_relationships: bool = False) -> Dict[str, Any]:
        """转换为字典"""
        result = super().to_dict(include_relationships)
        
        # 添加计算属性
        result.update({
            'features_list': self.get_features_list(),
            'raw_response_dict': self.get_raw_response_dict(),
            'confidence_level': self.confidence_level
        })
        
        return result
